package OBS;

import Errorhandler.ErrorLogger;
import GUI.ShowPopUp;
import java.io.File;
import java.io.FileNotFoundException;
import java.util.GregorianCalendar;
import java.util.Scanner;

/**
 *
 * Evt. fejl skrives til error log. Dog kan der opstå en fejl der ikke kan
 * logges hvis der ikke er skriverettighed til log bibliotektet. Det er
 * Organisators driftafdelings opgave at sikre at der til enhver tid er skrive-
 * rettighed til log biblioteket. Alternativ kan der skrives til OS event log,
 * det rette sted at angive den kode er markeret med kommentaren
 * SKRIV_TIL_OS_EVENT_LOG. Organisators drift afdeling vælger selv hvilken
 * løsning de foretrækker og står selv for en eventuel implementering.
 *
 * @author Jesper Wistoft
 * Genererer emails med batch rapporter
 */
public class SystemToHTML {
    private static final File parent = new File(System.getProperty("user.dir"));
    private static String reportTemplate = readTemplate("defaultReportSimple");
    private static String detailTemplate = readTemplate("defaultDetailsetSimple");
    private static String logDir = System.getProperty("user.dir") + File.separator + "log" + File.separator;
    private static String logName = "SystemToHTMLErrors.log";

    /**
     * Læser en html template der angiver udseendet af emailen
     * @param templateName navn på templaten, templaten skal være placeret i
     * systemets tool/html bibliotek
     * @return html template
     */
    public static String readTemplate(String templateName)
    {
        File template = new File(parent+File.separator+"tools"+File.separator+"HTML"+File.separator+templateName+".HTML");
        Scanner in;
        String ret = "";
        try {
            in = new Scanner(template);

            while(in.hasNext())
            {
                    ret+=in.nextLine();
            }
        } catch (FileNotFoundException ex) {
            ShowPopUp.showMessage ("E-mail skabelon kunne ikke indlæses. \n Kontakt driften");
            try {
                ErrorLogger.writeToErrorLog(logDir+logName,"Programfejl: " + ex.getMessage());
            } catch (Exception ex1){} // fejl hvis der ikke kan skrives til log kan ikke håndteres, SKRIV_TIL_OS_EVENT_LOG
        }

        return ret;
    }

    /**
     * Genererer en oversigt for alle batchkørsler hos en customer
     * @param customer den customer hvis oplysninger der ønskes
     * @return indholdet i oversigten (html)
     */
    public static String generateHTML(Customer customer)
    {
        BatchReportSystem[] reportSystems = customer.getBatchReportSystems();
        String reportsReturn = "";
                       
        for (int i = 0; i < reportSystems.length; i++) {
            BatchReport[] reports = reportSystems[i].getBatchReports();
            if (reports.length == 0) {
                return "***Ingen rapporter*** Kontakt Organisator";
            }
            for (int j = 0; j < reports.length; j++) {
                String HTMLreport = reportTemplate;
                //Rapportnavn
                HTMLreport = HTMLreport.replace("{ReportName}", reports[j].getName());
                //blev batch kørslen gennemført?
                if(reports[j].getSuccess())
                    HTMLreport = HTMLreport.replace("{Status}", "Gennemført");
                else
                    HTMLreport = HTMLreport.replace("{Status}", "Ej Gennemført");
                //Starttid
                GregorianCalendar startTimeCal = reports[j].getBatchStartTime();
                String startTime = ""+startTimeCal.getTime();
                HTMLreport = HTMLreport.replace("{StartTime}", startTime);
                //Sluttid
                GregorianCalendar endTimeCal = reports[j].getBatchEndTime();
                String endTime = ""+endTimeCal.getTime();
                HTMLreport = HTMLreport.replace("{EndTime}", endTime);
                //Forløbet tid
                HTMLreport = HTMLreport.replace("{TotalTime}", elapsedTime(endTimeCal, startTimeCal));
                //Statusbesked
                HTMLreport = HTMLreport.replace("{Messages}", reports[j].getStatusMessage());
                //Detaljesæt - se metoden readDetailSet
                BatchReportDetailSet[] detailSet = reports[j].getBatchReportDetailSets();
                HTMLreport = HTMLreport.replace("{Details}", readDetailSet(detailSet));
                reportsReturn = reportsReturn + HTMLreport;
           }
       }
        //søg string igennem for danske bogstaver og substituerer dem med html
        //escaped char
        for(int i = 0; i<reportsReturn.length(); i++)
        {
            char c;

            c = reportsReturn.charAt(i);

            if(c == 'æ' || c == 'Æ')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }
            if(c == 'ø' || c == 'Ø')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }
            if(c == 'å' || c == 'Å')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }
        }
        
        return reportsReturn+"</body> </html>";
    }

    /**
     * Genererer en batchreport email til en subscriber
     * @param subscriber den subscriber hvis oplysninger vi ønsker
     * @return den mail der skal sendes (html)
     */
     public static String generateHTML(OBSReportSubscriber subscriber)
    {
        OBSReportSubscription subscription = subscriber.getOBSReportSubscription();
        BatchReportSystem[] reportSystems = subscription.getBatchReportSystems();
        String reportsReturn = "";

        for (int i = 0; i < reportSystems.length; i++) {
            BatchReport[] reports = reportSystems[i].getBatchReports();
            if (reports.length == 0) {
                return "***Ingen rapporter*** Kontakt Organisator";
            }
            for (int j = 0; j < reports.length; j++) {
                String HTMLreport = reportTemplate;
                //Rapportnavn
                HTMLreport = HTMLreport.replace("{ReportName}", reports[j].getName());
                //blev batch kørslen gennemført?
                if(reports[j].getSuccess())
                    HTMLreport = HTMLreport.replace("{Status}", "Gennemført");
                else
                    HTMLreport = HTMLreport.replace("{Status}", "Ej Gennemført");
                //Starttid
                GregorianCalendar startTimeCal = reports[j].getBatchStartTime();
                String startTime = ""+startTimeCal.getTime();
                HTMLreport = HTMLreport.replace("{StartTime}", startTime);
                //Sluttid
                GregorianCalendar endTimeCal = reports[j].getBatchEndTime();
                String endTime = ""+endTimeCal.getTime();
                HTMLreport = HTMLreport.replace("{EndTime}", endTime);
                //Forløbet tid
                HTMLreport = HTMLreport.replace("{TotalTime}", elapsedTime(endTimeCal, startTimeCal));
                //Statusbesked
                HTMLreport = HTMLreport.replace("{Messages}", reports[j].getStatusMessage());
                //Detaljesæt - se metoden readDetailSet
                BatchReportDetailSet[] detailSet = reports[j].getBatchReportDetailSets();
                HTMLreport = HTMLreport.replace("{Details}", readDetailSet(detailSet));
                reportsReturn = reportsReturn + HTMLreport;
           }
       }
        //søg string igennem for danske bogstaver og substituerer dem med html
        //escaped char
        for(int i = 0; i<reportsReturn.length(); i++)
        {
            char c;

            c = reportsReturn.charAt(i);

            if(c == 'æ' || c == 'Æ')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }
            if(c == 'ø' || c == 'Ø')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }
            if(c == 'å' || c == 'Å')
            {
                reportsReturn = reportsReturn.replace(Character.toString(c), escapeHTML(Character.toString(c)));
            }

        }

        return reportsReturn;
    }

    /**
     * Udregner et tidsrum der går mellem to GregorianCalendar objekter
     * @param end starttidspunkt
     * @param start sluttidspunkt
     * @return den tid der er gået i læsbart format
     */
    private static String elapsedTime(GregorianCalendar end, GregorianCalendar start)
    {
        GregorianCalendar d = new GregorianCalendar();
        d.setTimeInMillis((end.getTimeInMillis()-start.getTimeInMillis()));

        //Dokumentation: http://stackoverflow.com/questions/175554/how-to-convert-milliseconds-into-human-readable-form
        return Long.toString((d.getTime().getTime()/86400000))+" dag(e), "+
                Long.toString(((d.getTime().getTime()/3600000))%24)+" time(r), "+
                Long.toString(((d.getTime().getTime()/60000))%60)+" minut(ter), "+
                Long.toString(((d.getTime().getTime()/1000))%60)+" sekund(er)";
    }
    
    public static String readDetailSet(BatchReportDetailSet[] detailSet) {
        String detailSetReturn = "";
        if (detailSet.length == 0) {
                return "***Ingen detaljesæt*** Kontakt Organisator";
            }
        for (int i = 0; i < detailSet.length; i++) {
            String detailSetHTML = detailTemplate;
            detailSetHTML = detailSetHTML.replace("{DetailSetName}", detailSet[i].getDetailSetName());
            detailSetHTML = detailSetHTML.replace("{TotalUPD}", ""+detailSet[i].getTotalUpdates());
            detailSetHTML = detailSetHTML.replace("{TotalCRE}", ""+detailSet[i].getTotalCreates());
            detailSetHTML = detailSetHTML.replace("{TotalDEL}", ""+detailSet[i].getTotalDeletes());
            detailSetHTML = detailSetHTML.replace("{TotalERR}", ""+detailSet[i].getTotalErrors());
            detailSetHTML = detailSetHTML.replace("{TotalSKI}", ""+detailSet[i].getTotalSkips());
            detailSetReturn = detailSetReturn+detailSetHTML;
        }
        return detailSetReturn;
    }
    
     private static String escapeHTML(String s) {
        //Dokumentation: http://java2s.com/Code/Java/Network-Protocol/EscapeHTMLspecialcharactersfromaString.htm

        //Metode anvendes hvis en string indeholder en char som HTML ikke kan læse/fejlfortolker
        StringBuilder sb = new StringBuilder();
        int n = s.length();
        for (int i = 0; i < n; i++) {
          char c = s.charAt(i);
          switch (c) {
          case '<':
            sb.append("&lt;");
            break;
          case '>':
            sb.append("&gt;");
            break;
          case '&':
            sb.append("&amp;");
            break;
          case '"':
            sb.append("&quot;");
            break;
          case 'à':
            sb.append("&agrave;");
            break;
          case 'À':
            sb.append("&Agrave;");
            break;
          case 'â':
            sb.append("&acirc;");
            break;
          case 'Â':
            sb.append("&Acirc;");
            break;
          case 'ä':
            sb.append("&auml;");
            break;
          case 'Ä':
            sb.append("&Auml;");
            break;
          case 'å':
            sb.append("&aring;");
            break;
          case 'Å':
            sb.append("&Aring;");
            break;
          case 'æ':
            sb.append("&aelig;");
            break;
          case 'Æ':
            sb.append("&AElig;");
            break;
          case 'ç':
            sb.append("&ccedil;");
            break;
          case 'Ç':
            sb.append("&Ccedil;");
            break;
          case 'é':
            sb.append("&eacute;");
            break;
          case 'É':
            sb.append("&Eacute;");
            break;
          case 'è':
            sb.append("&egrave;");
            break;
          case 'È':
            sb.append("&Egrave;");
            break;
          case 'ê':
            sb.append("&ecirc;");
            break;
          case 'Ê':
            sb.append("&Ecirc;");
            break;
          case 'ë':
            sb.append("&euml;");
            break;
          case 'Ë':
            sb.append("&Euml;");
            break;
          case 'ï':
            sb.append("&iuml;");
            break;
          case 'Ï':
            sb.append("&Iuml;");
            break;
          case 'ô':
            sb.append("&ocirc;");
            break;
          case 'Ô':
            sb.append("&Ocirc;");
            break;
          case 'ö':
            sb.append("&ouml;");
            break;
          case 'Ö':
            sb.append("&Ouml;");
            break;
          case 'ø':
            sb.append("&oslash;");
            break;
          case 'Ø':
            sb.append("&Oslash;");
            break;
          case 'ß':
            sb.append("&szlig;");
            break;
          case 'ù':
            sb.append("&ugrave;");
            break;
          case 'Ù':
            sb.append("&Ugrave;");
            break;
          case 'û':
            sb.append("&ucirc;");
            break;
          case 'Û':
            sb.append("&Ucirc;");
            break;
          case 'ü':
            sb.append("&uuml;");
            break;
          case 'Ü':
            sb.append("&Uuml;");
            break;
          case '®':
            sb.append("&reg;");
            break;
          case '©':
            sb.append("&copy;");
            break;
          case '€':
            sb.append("&euro;");
            break;
          case ' ':
            sb.append("&nbsp;");
            break;

          default:
            sb.append(c);
            break;
          }
        }
        return sb.toString();
  }
}
